<!-- 防火墙管理 -->
<template>
  <div v-loading="hostLoading">
    <div class="search-btn">
      <div @keydown.enter="getTableList">
        <div class="firwall-state">
          防火墙状态：<el-switch v-model="state" @change="handleFirwallState" />
        </div>
        <el-select v-model="queryParam.hostId" placeholder="请选择主机" @change="handleHostIdChange">
          <el-option v-for="host in hosts" :key="host.id" :value="host.id" :label="host.name"></el-option>
        </el-select>

        <el-button type="primary"  @click="getTableList">搜索</el-button>
        <el-button type="success"  @click="save" :loading="saveLoading">保存</el-button>
      </div>
      <div>
        <el-button type="primary"  @click="openEdit()">新增</el-button>
      </div>
    </div>
    <el-table ref="table" :data="table.list" border v-loading="table.loading" :empty-text="table.emptyText">
      
      <el-table-column prop="family" label="协议族" sortable :formatter="formatFamily" :filters="enums.family" :filter-method="(val, row)=>filterHandler('family', val, row)"></el-table-column>
      <el-table-column prop="description" label="名称" sortable :formatter="formatName"></el-table-column>
      <el-table-column prop="source" label="来源" sortable :formatter="formatSource"></el-table-column>
      <el-table-column prop="port" label="端口" sortable :formatter="formatPort"></el-table-column>
      <el-table-column prop="protocol" label="协议" sortable width="95px" :formatter="formatProtocol" :filters="enums.protocol" :filter-method="(val, row)=>filterHandler('protocol', val, row)"></el-table-column>
      <el-table-column prop="service" label="服务" sortable :formatter="formatService"></el-table-column>
      <el-table-column prop="action" label="动作" sortable width="95px" :formatter="formatAction" column-key="action" :filters="enums.action" :filter-method="(val, row)=>filterHandler('action', val, row)"></el-table-column>
      <el-table-column label="操作" width="160px" fixed="right">
        <template #default="{row}">
          <el-button type="primary" size="small" @click="openEdit(row)">编辑</el-button>
          <el-button type="warning" size="small" @click="deleteRow($event, row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

  <el-popconfirm
    v-model:visible="deletePopover.visible"
    ref="popoverRef"
    :virtual-ref="deletePopover.btnRef"
    trigger="click"
    title="确认删除这个规则？"
    virtual-triggering
    @confirm="doDeleteRow"
  >
  </el-popconfirm>

    <FirewallEdit ref="edit" @confirm="handleConfirm"></FirewallEdit>
  </div>
</template>

<script>

import FirewallApi from '@/api/firewall.api';
import HostApi from '@/api/host.api';

import FirewallEdit from './edit.vue';

import enums from './enums';

export default {
  components: {FirewallEdit},
  data () {
    return {
      hostId: this.$route.query.hostId,
      state: false,
      hosts: null,
      hostLoading: true,
      saveLoading: false,
      enums: enums,
      queryParam: {},
      deletePopover: {
        btnRef: null,
        visible: false,
        data: null
      },
      table: {
        list: [],
        loading: [],
        emptyText: null
      }
    };
  },
  created(){
    this.getTableList();
  },
  methods: {
    handleHostIdChange(id){
      this.hostId = id;
      this.$router.push({query: {hostId: id}});
      this.getTableList();
    },
    getHostList(){
      let self = this;
      self.hostLoading = true;
      return HostApi.page().then(res => {
        self.hosts = res;
        return res;
      }).finally(() => {
        self.hostLoading = false;
      });
    },
    getTableList(){
      let self = this;
      if(!self.hostId){
        self.$message('请选择主机');
        self.table.emptyText = '请选择主机';
        self.table.loading = false;
        self.getHostList();
        return;
      }
      if(!self.hosts){
        self.table.list = [];
        self.queryParam.hostId = parseInt(self.$route.query.hostId);
        self.getHostList().then(()=>{
          self.getTableList();
        });
        return;
      }

      self.table.loading = true;
      FirewallApi.info(self.queryParam.hostId).then(res => {
        self.table.list = res.rules;
        self.state = res.state;
      }).catch(err => {
        self.table.emptyText = err.data.message;
      }).finally(() => {
        self.table.loading = false;
      });

    },
    save(){
      let self = this;
      self.$confirm('确认更新防火墙规则？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        self.saveLoading = true;
        FirewallApi.updateRule(self.hostId, self.table.list).then(() => {
          self.$success('保存成功');
        });
      }).finally(() => {
        self.saveLoading = false;
      });
      console.log(self.table.list);
    },
    openEdit(row){
      this.$refs.edit.show(row, this.hostId);
    },
    handleConfirm(mode, data, src){
      if(mode == 'add'){
        this.table.list.push(data);
      } else if(mode == 'edit'){
        Object.assign(src, data);
      }
    },

    handleFirwallState(state){
      FirewallApi.updateState(this.hostId, state).then(() => {
        if(state){
          this.$success('防火墙已开启');
        } else {
          this.$success('防火墙已关闭');
        }
      });
    },

    doDeleteRow(){
      let self = this;
      self.$message.success('已删除，记得保存');
      self.table.list.remove(self.deletePopover.data);
    },
    deleteRow(event, row){
      let self = this;
      self.deletePopover.btnRef = event.currentTarget;
      self.deletePopover.visible = true;
      self.deletePopover.data = row;
    },

    filterHandler(key, value, row){
      return row[key] == value;
    },

    formatName(row){
      let val = 'ALL';
      if(row.type == 'rule'){
        val = row.description;
      } else {
        val = row.type;
      }
      return val;
    },
    formatPort(row){
      let val = '';
      if(row.type == 'rule'){
        val =  row.port?.port;
      } else if(row.type == 'port'){
        val =  row.port;
      } else {
        val =  '';
      }
      return val;
    },
    formatProtocol(row){
      let val = '';
      if(row.type == 'rule'){
        val =  row.port?.protocol;
      } else if(row.type == 'port'){
        val =  row.protocol;
      }else {
        val =  '';
      }
      return val;
    },
    formatService(row){
      let val = '';
      if(row.type == 'rule'){
        val =  row.service?.name;
      } else if(row.type == 'service'){
        val =  row.name;
      }else {
        val =  '';
      }
      return val;
    },
    formatSource(row){
      let val = 'ALL';
      if(row.type == 'rule'){
        val =  row.source?.address;
      } else if(row.type == 'source'){
        val =  row.address;
      }else {
        val =  'ALL';
      }
      return val || 'ALL';
    },
    formatFamily(row){
      let val = 'ALL';
      if(row.type == 'rule'){
        val =  row.family;
      }else {
        val =  'ALL';
      }
      return val;
    },
    formatAction(row){
      if(row.type == 'rule'){
        return row.action == 'accept'? '允许':'拒绝';
      }else{
        return '允许';
      }
    },
  }
};
</script>

<style scoped>
.firwall-state{
  display: inline-block;
  margin-right: 10px;
}
</style>
